package com.heima.schedule.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.common.constants.ScheduleConstants;
import com.heima.common.redis.CacheService;
import com.heima.model.schedule.dtos.Task;
import com.heima.model.schedule.pojos.Taskinfo;
import com.heima.model.schedule.pojos.TaskinfoLogs;
import com.heima.schedule.mapper.TaskinfoLogsMapper;
import com.heima.schedule.mapper.TaskinfoMapper;
import com.heima.schedule.service.TaskService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Calendar;
import java.util.Date;

@Service
@Transactional
public class TaskServiceImpl implements TaskService {
    @Autowired
    private TaskinfoMapper taskinfoMapper;
    @Autowired
    private TaskinfoLogsMapper taskinfoLogsMapper;
    @Autowired
    private CacheService cacheService;

    /**
     * 添加任务
     *
     * @param task 任务对象
     * @return 任务id
     */
    @Override
    public void addTask(Task task) {
        //把任务数据添加到数据库
    boolean success = addTaskToDb(task);
        //把任务添加到redis-不是所有的任务都要添加到redis(立即执行，未来5分钟要执行的任务)
        if(success){
            addTaskRedis(task);
        }
    }

    /**
     * 添加数据到redis
     * @param task
     */
    private void addTaskRedis(Task task) {
    //1.redis的数据是有key的我们需要构建
        String key = task.getTaskType() + "_" + task.getPriority();

        //2.使用日历类来完成时间的操作
        //2.1用当前时间初始化一个日历
        Calendar instance = Calendar.getInstance();
        //2.2把日历时间设置到的未来的五分钟
        instance.add(Calendar.MINUTE,5);
        long futureTime = instance.getTimeInMillis();

        //3.任务执行时间小于等于当前时间 --添加到立即执行的list任务
        if(task.getExecuteTime() <= System.currentTimeMillis()){
            cacheService.lLeftPush(ScheduleConstants.TOPIC + key, JSON.toJSONString(task));

        }else if(task.getExecuteTime() <= futureTime){
            //4.任务执行时间小于等于当前时间 + 5分钟
        cacheService.zAdd(ScheduleConstants.FUTURE + key,JSON.toJSONString(task),task.getExecuteTime());

        }

    }

    /**
     * 添加任务到数据库
     * @param task
     * @return
     */
    private boolean addTaskToDb(Task task) {
        boolean flag = true;
        //1.添加TaskInfo表的数据
        Taskinfo taskinfo = new Taskinfo();
        //将数据拷贝
        BeanUtils.copyProperties(task,taskinfo);
        //存入时间
        taskinfo.setExecuteTime(new Date(task.getExecuteTime()));
        int status = taskinfoMapper.insert(taskinfo);

        //2.添加TaskInfoLogs日志
        TaskinfoLogs taskinfoLogs = new TaskinfoLogs();
        BeanUtils.copyProperties(task,taskinfoLogs);
        //存入时间
        taskinfoLogs.setExecuteTime(new Date(task.getExecuteTime()));
        //需要给一个初始值，给mybatis-plus更新做维护的，没有值就没办法维护
        taskinfoLogs.setVersion(1);
        //存入状态为0
        taskinfoLogs.setStatus(ScheduleConstants.SCHEDULED);

        //将状态添加到数据库
        int status2 = taskinfoLogsMapper.insert(taskinfoLogs);

        return status == 1 && status2 == 1;

    }
}
